
#include "bsp.h"

static crm_clocks_freq_type sys_freq = {0};
 __IO uint16_t adc_buff[BSP_ADC_CH_NUM] = {0};

/**
  * @brief  system clock config program
  * @note   the system clock is configured as follow:
  *         system clock (sclk)   = hext / 2 * pll_mult
  *         system clock source   = pll (hext)
  *         - hext                = HEXT_VALUE
  *         - sclk                = 192000000
  *         - ahbdiv              = 1
  *         - ahbclk              = 192000000
  *         - apb2div             = 2
  *         - apb2clk             = 96000000
  *         - apb1div             = 2
  *         - apb1clk             = 96000000
  *         - pll_mult            = 48
  *         - pll_range           = GT72MHZ (greater than 72 mhz)
  * @param  none
  * @retval none
  */
void system_clock_config(void)
{
  /* reset crm */
  crm_reset();

  crm_clock_source_enable(CRM_CLOCK_SOURCE_HEXT, TRUE);

   /* wait till hext is ready */
  while(crm_hext_stable_wait() == ERROR)
  {
  }

  /* config pll clock resource */
  crm_pll_config(CRM_PLL_SOURCE_HEXT_DIV, CRM_PLL_MULT_48, CRM_PLL_OUTPUT_RANGE_GT72MHZ);

  /* config hext division */
  crm_hext_clock_div_set(CRM_HEXT_DIV_2);

  /* enable pll */
  crm_clock_source_enable(CRM_CLOCK_SOURCE_PLL, TRUE);

  /* wait till pll is ready */
  while(crm_flag_get(CRM_PLL_STABLE_FLAG) != SET)
  {
  }

  /* config ahbclk */
  crm_ahb_div_set(CRM_AHB_DIV_1);

  /* config apb2clk, the maximum frequency of APB1/APB2 clock is 120 MHz */
  crm_apb2_div_set(CRM_APB2_DIV_2);

  /* config apb1clk, the maximum frequency of APB1/APB2 clock is 120 MHz  */
  crm_apb1_div_set(CRM_APB1_DIV_2);

  /* enable auto step mode */
  crm_auto_step_mode_enable(TRUE);

  /* select pll as system clock source */
  crm_sysclk_switch(CRM_SCLK_PLL);

  /* wait till pll is used as system clock source */
  while(crm_sysclk_switch_status_get() != CRM_SCLK_PLL)
  {
  }

  /* disable auto step mode */
  crm_auto_step_mode_enable(FALSE);

  /* update system_core_clock global variable */
  system_core_clock_update();
}




/* IO */
static void bsp_io_init(void)
{
    gpio_init_type gpio_init_struct;
    
    /* set default parameter */
    gpio_default_para_init(&gpio_init_struct);
    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    
    //PA0--302_SDA, PA1--302_SCL
    gpio_init_struct.gpio_pins = GPIO_PINS_0|GPIO_PINS_1;
	gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN;
    //gpio_init_struct.gpio_out_type  = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
	gpio_init(GPIOA, &gpio_init_struct);
   
    
    //PA2--302_INT, PA10--RXD1
    gpio_init_struct.gpio_pins = GPIO_PINS_2|GPIO_PINS_10;
	gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_pull = GPIO_PULL_UP;
	gpio_init(GPIOA, &gpio_init_struct);
    //PA3--ADC-IN3, PA6--ADC_IN6
    gpio_init_struct.gpio_pins = GPIO_PINS_3|GPIO_PINS_6;
	gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
	gpio_init(GPIOA, &gpio_init_struct);
    //PA4--DAC1, PA5--DAC2
    /* once the dac is enabled, the corresponding gpio pin is automatically
        connected to the dac converter. in order to avoid parasitic consumption,
        the gpio pin should be configured in analog */
    gpio_init_struct.gpio_pins = GPIO_PINS_4 | GPIO_PINS_5;
    gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
    gpio_init(GPIOA, &gpio_init_struct);
    //PA7--TMR3_2, PA8--TMR1_1, PA9--TXD1, 
    gpio_init_struct.gpio_pins = GPIO_PINS_7|GPIO_PINS_8|GPIO_PINS_9;
    gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
    gpio_init_struct.gpio_out_type  = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
    gpio_init(GPIOA, &gpio_init_struct);
    
    //PB0--TMR3_3
    gpio_init_struct.gpio_pins = GPIO_PINS_0;
    gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
    gpio_init_struct.gpio_out_type  = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
    gpio_init(GPIOB, &gpio_init_struct);
    //PB1--ADC-IN9,
    gpio_init_struct.gpio_pins = GPIO_PINS_1;
	gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
	gpio_init(GPIOB, &gpio_init_struct);
    //PB3--SPI3_SCK, PB4--SPI3_MISO, PB5--SPI3_MOSI
    gpio_init_struct.gpio_pins = GPIO_PINS_3|GPIO_PINS_4|GPIO_PINS_5;
    gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
    gpio_init_struct.gpio_out_type  = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
    gpio_init(GPIOB, &gpio_init_struct);
    //PB8, PB9 initial in board.c
    
    //PB10--I2C2_SCL, PB11-I2C2_SDA
    gpio_init_struct.gpio_pins = GPIO_PINS_10|GPIO_PINS_11;
	//gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
	gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
	gpio_init(GPIOB, &gpio_init_struct);
    //PB12, PB14--OUT
    gpio_init_struct.gpio_pins = GPIO_PINS_12|GPIO_PINS_14;
	gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_pull = GPIO_PULL_UP;
	gpio_init(GPIOB, &gpio_init_struct);
    //PB13--SPI2_SCK, PB15--SPI2_MOSI
    gpio_init_struct.gpio_pins = GPIO_PINS_13|GPIO_PINS_15;
	gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_pull = GPIO_PULL_UP;
	gpio_init(GPIOB, &gpio_init_struct);
   
    //PC0, PC4, PC6, PC7 --OUT
    gpio_init_struct.gpio_pins = GPIO_PINS_0|GPIO_PINS_4|GPIO_PINS_6|GPIO_PINS_7;
	gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
	gpio_init(GPIOC, &gpio_init_struct);
    //PC1, PC2, PC14, PC15 --IN UP
    gpio_init_struct.gpio_pins = GPIO_PINS_1|GPIO_PINS_2|GPIO_PINS_14|GPIO_PINS_15;
	gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_pull = GPIO_PULL_UP;
	gpio_init(GPIOC, &gpio_init_struct);
    //PC5--ADC-IN15,
    gpio_init_struct.gpio_pins = GPIO_PINS_5;
	gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
	gpio_init(GPIOC, &gpio_init_struct);
    //PC8--TMR8_3, PC9--TMR8_4
    gpio_init_struct.gpio_pins = GPIO_PINS_8|GPIO_PINS_9;
    gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
    gpio_init_struct.gpio_out_type  = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
    gpio_init(GPIOC, &gpio_init_struct);
    //PC12--IN DOWM
    gpio_init_struct.gpio_pins = GPIO_PINS_12;
	gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_pull = GPIO_PULL_DOWN;
	gpio_init(GPIOC, &gpio_init_struct);
   
    //PD2--OUT
    gpio_init_struct.gpio_pins = GPIO_PINS_2;
	gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
	gpio_init(GPIOD, &gpio_init_struct);
}

//10kHz
static void bsp_timer1_init(void)
{
    tmr_output_config_type tmr_oc_init_structure;

    /* tmr3 time base configuration */
    tmr_base_init(TMR1, 1000, (uint16_t)(sys_freq.sclk_freq / 10000000) - 1);
    tmr_cnt_dir_set(TMR1, TMR_COUNT_UP);
    tmr_clock_source_div_set(TMR1, TMR_CLOCK_DIV1);

    tmr_output_default_para_init(&tmr_oc_init_structure);
    tmr_oc_init_structure.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
    tmr_oc_init_structure.oc_idle_state = FALSE;
    tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
    tmr_oc_init_structure.oc_output_state = TRUE;
    tmr_oc_init_structure.occ_polarity = TMR_OUTPUT_ACTIVE_LOW;
    tmr_oc_init_structure.occ_idle_state = FALSE;
    
    tmr_output_channel_config(TMR1, TMR_SELECT_CHANNEL_1, &tmr_oc_init_structure);
    tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_1, 900);

    tmr_output_enable(TMR1, TRUE);

    /* tmr enable counter */
    tmr_counter_enable(TMR1, TRUE);      
}

//4KHz
static void bsp_timer2_init(void)
{
    tmr_output_config_type tmr_oc_init_structure;

    /* tmr3 time base configuration */
    tmr_base_init(TMR2, 1000, (uint16_t)(sys_freq.sclk_freq / 4000000) - 1);
    tmr_cnt_dir_set(TMR2, TMR_COUNT_UP);
    tmr_clock_source_div_set(TMR2, TMR_CLOCK_DIV1);

    tmr_output_default_para_init(&tmr_oc_init_structure);
    tmr_oc_init_structure.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
    tmr_oc_init_structure.oc_idle_state = FALSE;
    tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
    tmr_oc_init_structure.oc_output_state = TRUE;
    tmr_output_channel_config(TMR2, TMR_SELECT_CHANNEL_1, &tmr_oc_init_structure);
    tmr_channel_value_set(TMR2, TMR_SELECT_CHANNEL_1, 0);
    tmr_output_channel_buffer_enable(TMR2, TMR_SELECT_CHANNEL_1, TRUE);

    tmr_output_channel_config(TMR2, TMR_SELECT_CHANNEL_2, &tmr_oc_init_structure);
    tmr_channel_value_set(TMR2, TMR_SELECT_CHANNEL_2, 0);
    tmr_output_channel_buffer_enable(TMR2, TMR_SELECT_CHANNEL_2, TRUE);


    tmr_period_buffer_enable(TMR2, TRUE);

    /* tmr enable counter */
    tmr_counter_enable(TMR2, TRUE);
}

//4KHz pwm
static void bsp_timer3_init(void)
{
    tmr_output_config_type tmr_oc_init_structure;

    /* tmr3 time base configuration */
    tmr_base_init(TMR3, 1000, (uint16_t)(sys_freq.sclk_freq / 4000000) - 1);
    tmr_cnt_dir_set(TMR3, TMR_COUNT_UP);
    tmr_clock_source_div_set(TMR3, TMR_CLOCK_DIV1);

    tmr_output_default_para_init(&tmr_oc_init_structure);
    tmr_oc_init_structure.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
    tmr_oc_init_structure.oc_idle_state = FALSE;
    tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
    tmr_oc_init_structure.oc_output_state = TRUE;

    tmr_output_channel_config(TMR3, TMR_SELECT_CHANNEL_2, &tmr_oc_init_structure);
    tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_2, 0);
    tmr_output_channel_buffer_enable(TMR3, TMR_SELECT_CHANNEL_2, TRUE);

    tmr_output_channel_config(TMR3, TMR_SELECT_CHANNEL_3, &tmr_oc_init_structure);
    tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_3, 0);
    tmr_output_channel_buffer_enable(TMR3, TMR_SELECT_CHANNEL_3, TRUE);

    tmr_period_buffer_enable(TMR3, TRUE);

    /* tmr enable counter */
    tmr_counter_enable(TMR3, TRUE);    
}

//24khz
static void bsp_timer8_init(void)
{
    tmr_output_config_type tmr_oc_init_structure;

    /* tmr8 time base configuration */
    tmr_base_init(TMR8, 1000, (uint16_t)(sys_freq.sclk_freq / 24000000) - 1);
    tmr_cnt_dir_set(TMR8, TMR_COUNT_UP);
    tmr_clock_source_div_set(TMR8, TMR_CLOCK_DIV1);

    tmr_output_default_para_init(&tmr_oc_init_structure);
    tmr_oc_init_structure.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
    tmr_oc_init_structure.oc_idle_state = FALSE;
    tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
    tmr_oc_init_structure.oc_output_state = TRUE;
    tmr_oc_init_structure.occ_polarity = TMR_OUTPUT_ACTIVE_LOW;
    tmr_oc_init_structure.occ_idle_state = FALSE;

    tmr_output_channel_config(TMR8, TMR_SELECT_CHANNEL_3, &tmr_oc_init_structure);
    tmr_channel_value_set(TMR8, TMR_SELECT_CHANNEL_3, 0);
    tmr_output_channel_buffer_enable(TMR8, TMR_SELECT_CHANNEL_3, TRUE);

    tmr_output_channel_config(TMR8, TMR_SELECT_CHANNEL_4, &tmr_oc_init_structure);
    tmr_channel_value_set(TMR8, TMR_SELECT_CHANNEL_4, 0);
    tmr_output_channel_buffer_enable(TMR8, TMR_SELECT_CHANNEL_4, TRUE);

    tmr_output_enable(TMR8, TRUE);

    /* tmr enable counter */
    tmr_counter_enable(TMR8, TRUE);    
    
}

static void bsp_timer12_init(void)
{
    tmr_output_config_type tmr_oc_init_structure;

    /* tmr3 time base configuration */
    tmr_base_init(TMR12, 1000, (uint16_t)(sys_freq.sclk_freq / 100000) - 1);
    tmr_cnt_dir_set(TMR12, TMR_COUNT_UP);
    tmr_clock_source_div_set(TMR12, TMR_CLOCK_DIV1);

    tmr_output_default_para_init(&tmr_oc_init_structure);
    tmr_oc_init_structure.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
    tmr_oc_init_structure.oc_idle_state = FALSE;
    tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
    tmr_oc_init_structure.oc_output_state = TRUE;
    tmr_output_channel_config(TMR12, TMR_SELECT_CHANNEL_2, &tmr_oc_init_structure);
    tmr_channel_value_set(TMR12, TMR_SELECT_CHANNEL_2, 0);
    tmr_output_channel_buffer_enable(TMR12, TMR_SELECT_CHANNEL_2, TRUE);
    
    tmr_period_buffer_enable(TMR12, TRUE);

    /* tmr enable counter */
    tmr_counter_enable(TMR12, TRUE);      
}

static void bsp_timer13_init(void)
{
    tmr_output_config_type tmr_oc_init_structure;

    /* tmr13 time base configuration */
    tmr_base_init(TMR13, 1000, (uint16_t)(sys_freq.sclk_freq / 24000000) - 1);
    tmr_cnt_dir_set(TMR13, TMR_COUNT_UP);
    tmr_clock_source_div_set(TMR13, TMR_CLOCK_DIV1);

    tmr_output_default_para_init(&tmr_oc_init_structure);
    tmr_oc_init_structure.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
    tmr_oc_init_structure.oc_idle_state = FALSE;
    tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
    tmr_oc_init_structure.oc_output_state = TRUE;
    tmr_output_channel_config(TMR13, TMR_SELECT_CHANNEL_1, &tmr_oc_init_structure);
    tmr_channel_value_set(TMR13, TMR_SELECT_CHANNEL_1, 0);
    tmr_output_channel_buffer_enable(TMR13, TMR_SELECT_CHANNEL_1, TRUE);
    
    tmr_period_buffer_enable(TMR13, TRUE);

    /* tmr enable counter */
    tmr_counter_enable(TMR13, TRUE);      
}

static void bsp_timer14_init(void)
{
    tmr_output_config_type tmr_oc_init_structure;

    /* tmr14 time base configuration */
    tmr_base_init(TMR14, 1000, (uint16_t)(sys_freq.sclk_freq / 100000) - 1);
    tmr_cnt_dir_set(TMR14, TMR_COUNT_UP);
    tmr_clock_source_div_set(TMR14, TMR_CLOCK_DIV1);

    tmr_output_default_para_init(&tmr_oc_init_structure);
    tmr_oc_init_structure.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
    tmr_oc_init_structure.oc_idle_state = FALSE;
    tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
    tmr_oc_init_structure.oc_output_state = TRUE;
    tmr_output_channel_config(TMR14, TMR_SELECT_CHANNEL_1, &tmr_oc_init_structure);
    tmr_channel_value_set(TMR14, TMR_SELECT_CHANNEL_1, 900);
    tmr_output_channel_buffer_enable(TMR14, TMR_SELECT_CHANNEL_1, TRUE);
    
    tmr_period_buffer_enable(TMR14, TRUE);

    /* tmr enable counter */
    tmr_counter_enable(TMR14, TRUE);      
}

static void bsp_spi2_init(void)
{
    spi_init_type spi_init_struct;
    spi_default_para_init(&spi_init_struct);
    spi_init_struct.transmission_mode = SPI_TRANSMIT_HALF_DUPLEX_TX;
    spi_init_struct.master_slave_mode = SPI_MODE_MASTER;
    spi_init_struct.mclk_freq_division = SPI_MCLK_DIV_2;
    spi_init_struct.first_bit_transmission = SPI_FIRST_BIT_MSB;
    spi_init_struct.frame_bit_num = SPI_FRAME_8BIT;
    spi_init_struct.clock_polarity = SPI_CLOCK_POLARITY_HIGH;
    spi_init_struct.clock_phase = SPI_CLOCK_PHASE_2EDGE;
    spi_init_struct.cs_mode_selection = SPI_CS_SOFTWARE_MODE;
    spi_init(SPI2, &spi_init_struct);
    spi_enable(SPI2, TRUE);
    
    spi_i2s_dma_transmitter_enable(SPI2, TRUE);
    nvic_irq_enable(DMA1_Channel2_IRQn, 3 , 0);
    dma_reset(DMA1_CHANNEL2);
}
static void bsp_dma_adc_init(void)
{
  dma_init_type dma_init_struct;
  crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE);
  nvic_irq_enable(DMA1_Channel1_IRQn, 5, 0);
  dma_reset(DMA1_CHANNEL1);
  dma_default_para_init(&dma_init_struct);
  dma_init_struct.buffer_size = BSP_ADC_CH_NUM;
  dma_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY;
  dma_init_struct.memory_base_addr = (uint32_t)adc_buff;
  dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_HALFWORD;
  dma_init_struct.memory_inc_enable = TRUE;
  dma_init_struct.peripheral_base_addr = (uint32_t)&(ADC1->odt);
  dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_HALFWORD;
  dma_init_struct.peripheral_inc_enable = FALSE;
  dma_init_struct.priority = DMA_PRIORITY_HIGH;
  dma_init_struct.loop_mode_enable = TRUE;
  dma_init(DMA1_CHANNEL1, &dma_init_struct);

  dma_interrupt_enable(DMA1_CHANNEL1, DMA_FDT_INT, TRUE);
  dma_channel_enable(DMA1_CHANNEL1, TRUE);
}
//100Hz
void bsp_timer4_init(void)
{
    
    tmr_output_config_type tmr_oc_init_structure;

    nvic_irq_enable(TMR4_GLOBAL_IRQn, 5, 0);
    /* tmr3 time base configuration */
    tmr_base_init(TMR4, 4000, (uint16_t)(sys_freq.sclk_freq / 400000) - 1);
    tmr_cnt_dir_set(TMR4, TMR_COUNT_UP);
    tmr_clock_source_div_set(TMR4, TMR_CLOCK_DIV1);

    tmr_output_default_para_init(&tmr_oc_init_structure);
    tmr_oc_init_structure.oc_mode = TMR_OUTPUT_CONTROL_HIGH;
    tmr_oc_init_structure.oc_idle_state = FALSE;
    tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
    tmr_oc_init_structure.oc_output_state = TRUE;

    tmr_output_channel_config(TMR4, TMR_SELECT_CHANNEL_4, &tmr_oc_init_structure);
    tmr_channel_value_set(TMR4, TMR_SELECT_CHANNEL_4, 3600);
    tmr_output_channel_buffer_enable(TMR4, TMR_SELECT_CHANNEL_4, TRUE);

    /* tmr4 int enable */
    tmr_interrupt_enable(TMR4, TMR_C4_INT | TMR_OVF_INT, TRUE);
    
    tmr_period_buffer_enable(TMR4, TRUE);

    /* tmr enable counter */
    tmr_counter_enable(TMR4, TRUE);    
}

void bsp_adc_init(void)
{
    adc_base_config_type adc_base_struct;
   
    crm_adc_clock_div_set(CRM_ADC_DIV_6); //120M/6=20M
    nvic_irq_enable(ADC1_2_IRQn, 0, 0);
    /* select combine mode */

    adc_combine_mode_select(ADC_INDEPENDENT_MODE);
    adc_base_default_para_init(&adc_base_struct);
    adc_base_struct.sequence_mode = TRUE;
    adc_base_struct.repeat_mode = FALSE;
    adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT;
    adc_base_struct.ordinary_channel_length = BSP_ADC_CH_NUM;
    adc_base_config(ADC1, &adc_base_struct);
    adc_ordinary_channel_set(ADC1, ADC_CHANNEL_3, 1, ADC_SAMPLETIME_239_5);  //D-
    adc_ordinary_channel_set(ADC1, ADC_CHANNEL_6, 2, ADC_SAMPLETIME_239_5);  //D+
    adc_ordinary_channel_set(ADC1, ADC_CHANNEL_16, 3, ADC_SAMPLETIME_239_5); //temp
    //adc_ordinary_channel_set(ADC1, ADC_CHANNEL_9, 4, ADC_SAMPLETIME_13_5);  //P_ADC_I
    //adc_ordinary_channel_set(ADC1, ADC_CHANNEL_15, 5, ADC_SAMPLETIME_13_5); //P_ADC_U
    adc_ordinary_conversion_trigger_set(ADC1, ADC12_ORDINARY_TRIG_SOFTWARE, TRUE);

    //adc_interrupt_enable(ADC1, ADC_CCE_INT, TRUE);
    adc_dma_mode_enable(ADC1, TRUE);
    adc_tempersensor_vintrv_enable(TRUE);
    
    adc_enable(ADC1, TRUE);
    adc_calibration_init(ADC1);
    while(adc_calibration_init_status_get(ADC1));
    adc_calibration_start(ADC1);
    while(adc_calibration_status_get(ADC1));
    
}

extern void usart1_preinit(void);

void bsp_init(void)
{
    SCB->VTOR = APP_BASE_ADDRESS;
    nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);	
    
    system_clock_config();
    crm_periph_clock_enable(CRM_SPI2_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_TMR2_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_TMR3_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_TMR4_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_TMR8_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_TMR12_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_TMR13_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_TMR14_PERIPH_CLOCK, TRUE);
	crm_periph_clock_enable(CRM_USART1_PERIPH_CLOCK, TRUE);
	crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOD_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_DMA2_PERIPH_CLOCK, TRUE);
	crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, TRUE);
    
    gpio_pin_remap_config(SWJTAG_MUX_010, TRUE);
    //gpio_pin_remap_config(SPI4_GMUX_0010, TRUE);
    //gpio_pin_remap_config(TMR2_MUX_11, TRUE);
    //gpio_pin_remap_config(TMR3_MUX_10, TRUE);
    //gpio_pin_remap_config(TMR4_GMUX_0001, TRUE);
    gpio_pin_remap_config(TMR1_GMUX_0001, TRUE);
    
    crm_clocks_freq_get(&sys_freq);
    dma_flexible_config(DMA1, FLEX_CHANNEL1, DMA_FLEXIBLE_ADC1);
    dma_flexible_config(DMA1, FLEX_CHANNEL2, DMA_FLEXIBLE_SPI2_TX);
    dma_flexible_config(DMA2, FLEX_CHANNEL1, DMA_FLEXIBLE_UART1_TX);
    dma_flexible_config(DMA2, FLEX_CHANNEL2, DMA_FLEXIBLE_UART1_RX);
    bsp_io_init();
    usart1_preinit();
    bsp_spi2_init();
    bsp_dma_adc_init();
    bsp_adc_init();
    nvic_irq_enable(USART1_IRQn, 5, 0);
}

void bsp_init_later(void)
{
    bsp_timer1_init();
    bsp_timer3_init();
    bsp_timer4_init();
    bsp_timer8_init();
/*    bsp_timer2_init();
    bsp_timer12_init();
    bsp_timer13_init();
    bsp_timer14_init();
    */
}
